package com.power.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.power.constant.ManagerContstants;
import com.power.domain.SysMenu;
import com.power.ex.handle.BussinessException;
import com.power.mapper.SysMenuMapper;
import com.power.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author dingchunlin
 * @description 针对表【sys_menu(菜单管理)】的数据库操作Service实现
 * @createDate 2024-07-10 15:12:14
 */
@Service
@CacheConfig(cacheNames = "com.power.service.impl.SysMenuServiceImpl")
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;

    /**
     * 根据用户ID查询菜单列表
     *
     * @param loginUserId 用户ID
     * @return 菜单列表
     */
    @Override
    @Cacheable(key = "#loginUserId")
    public Set<SysMenu> queryUserMenuListByUserId(Long loginUserId) {
        Set<SysMenu> menus = sysMenuMapper.queryUserMenuListByUserId(loginUserId);
        //将查询出来的数据转换成树形结构
        return transformTree(menus, 0L);
    }

    /**
     * 查询所有菜单列表
     * @return 菜单列表
     */
    @Override
    @Cacheable(key = ManagerContstants.SYS_ALL_MENU_KEY)
    public List<SysMenu> queryAllMenuList() {
        List<SysMenu> sysMenuList = sysMenuMapper.selectList(null);
        return sysMenuList;
    }

    /**
     * 保存菜单信息
     * @param sysMenu 菜单信息
     * @return 保存成功返回true，否则返回false
     */
    @Override
    @CacheEvict(key = ManagerContstants.SYS_ALL_MENU_KEY)
    public Boolean saveSysMenu(SysMenu sysMenu) {
        return sysMenuMapper.insert(sysMenu) > 0;
    }

    /**
     * 修改菜单信息
     * @param sysMenu
     * @return
     */
    @Override
    @CacheEvict(key = ManagerContstants.SYS_ALL_MENU_KEY)
    public Boolean modifySysMenu(SysMenu sysMenu) {
        // 获取菜单类型
        Integer type = sysMenu.getType();
        // 如果菜单类型为一级菜单,则父节点ID为0
        if (0 == type){
            sysMenu.setParentId(0L);
        }
        // 修改菜单信息
        return sysMenuMapper.updateById(sysMenu) > 0;
    }

    /**
     * 根据菜单ID删除菜单信息
     * 注意:如果当前菜单有子节点则不能删除
     * @param menuId 菜单ID
     * @return 删除成功返回true，否则返回false
     */
    @Override
    @CacheEvict(key = ManagerContstants.SYS_ALL_MENU_KEY)
    public Boolean removeSysMenuById(Long menuId) {
        // 判断是否存在子菜单
        List<SysMenu> sysMenuList = sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getParentId, menuId));
        // 如果存在子菜单,则不能删除
        if (CollectionUtils.isNotEmpty(sysMenuList) || sysMenuList.size() > 0){
            throw new BussinessException("当前菜单存在子菜单,不能删除");
        }
        // 删除菜单信息
        return sysMenuMapper.deleteById(menuId) > 0;
    }

    /**
     * 将菜单列表转换成树形结构
     *
     * @param menus 菜单列表
     * @return 树形结构菜单列表
     */
    private Set<SysMenu> transformTree(Set<SysMenu> menus, Long pid) {
        // 第一种情况:已经知道了层级关系
        /*// 1.找出所有的父节点
        Set<SysMenu> roots = menus.stream()
                .filter(m -> m.getParentId().equals(pid))
                .collect(Collectors.toSet());
        // 2.遍历父节点,递归查找子节点
        roots.forEach(root ->{
            Set<SysMenu> collect = menus.stream()
                    .filter(m -> m.getParentId().equals(root.getMenuId()))
                    .collect(Collectors.toSet());
            root.setList(collect);
        });*/
        // 第二种情况:不知道层级关系
        // 1.找出所有的父节点
        Set<SysMenu> roots = menus.stream()
                .filter(m -> m.getParentId().equals(pid))
                .collect(Collectors.toSet());
        // 2.遍历父节点,递归查找子节点
        roots.forEach( r -> r.setList(transformTree(menus, r.getMenuId())));

        //返回结果
        return roots;
    }
}




